package main

import (
	"context"
	"os"

	"gorm.io/gorm"

	"torler.com/qingyue/apps/spider/config"
	"torler.com/qingyue/apps/spider/internal/core"
	"torler.com/qingyue/apps/spider/internal/core/task"
	"torler.com/qingyue/apps/spider/internal/tasks"
	"torler.com/qingyue/common/model"
	"torler.com/qingyue/common/types"
	"torler.com/qingyue/pkg/logger"
	"torler.com/qingyue/pkg/runtime"
	"torler.com/qingyue/pkg/storage"
)

func main() {
	if err := config.LoadConfig(); err != nil {
		panic(err)
	}
	conf := config.GetConfig()

	logger.Init(conf.Log)
	db := storage.NewDatabase(conf.DB)

	db.Connect()
	autoMigrate(db.DB)

	tasks.InitBrowser(logger.Default())

	// 创建运行时管理器
	runtimeMgr := runtime.NewServer("Spider Service")

	// 初始化核心
	appContext := core.NewAppConext(conf, db.DB, logger.Default())
	taskMgr := task.NewTaskManager(appContext)
	taskMgr.SetRunnerCreator(provider)
	// 添加爬虫服务到运行时管理器
	runtimeMgr.Add(taskMgr)

	registerSchedTask(appContext, taskMgr)

	context := context.Background()

	// 运行服务
	if err := runtimeMgr.Run(context); err != nil {
		logger.Default().Error("运行时管理器错误", "error", err)
		os.Exit(1)
	}

}

// provider 函数根据 RunnerName 创建对应的 Runner 实例
func provider(name types.RunnerName) task.Runner {
	switch name {
	case tasks.RUNNER_LAST_UPDATE:
		return tasks.NewLastUpdateSpider()
	case tasks.RUNNER_INSTORE_BOOK:
		return tasks.NewBookInstoreTask()
	case tasks.RUNNER_PUBLISH_SPIDER_BOOK_CHANNEL:
		return tasks.NewPublishBookChannelSpiderTask()
	case tasks.RUNNER_SPIDER_CBOOK:
		return tasks.NewCBookInfoSpider()
	case tasks.RUNNER_LOCAL_BOOK_PROCESS:
		return tasks.NewLocalBookProcessTask()
	}

	return nil
}

// 注册爬虫到任务管理器中
func registerSchedTask(app *core.AppContext, mgr *task.TaskManager) {
	tasks.AddSpider(app, mgr)

}

func autoMigrate(db *gorm.DB) {
	db.AutoMigrate(&model.RawBook{})
	db.AutoMigrate(&model.LastestCBook{})
	db.AutoMigrate(&model.BookInfo{})
	db.AutoMigrate(&model.ChapterInfo{})

	// // 为sp_lbook表添加全文索引和复合索引
	// db.Exec(`ALTER TABLE sp_lbook ADD FULLTEXT INDEX ft_file_name (file_name) WITH PARSER ngram;`)
	// db.Exec(`CREATE INDEX idx_lbi_meta_subfix_delat ON sp_lbook(meta_state, subfix, delat);`)
}
